#ifndef SPYNET_NET_INET_SESSION_H_
#define SPYNET_NET_INET_SESSION_H_

#include "packet_header.h"
#include "io_buffer.h"

namespace Net
{
	class INetSession : public boost::enable_shared_from_this<INetSession>
	{
	public:
		enum
		{
			STATE_RELEASE,
			STATE_CLOSE,
			STATE_INVALID,
			STATE_CONNECT,
			STATE_HANDSHAKE,
			STATE_RUNNING,
		};

	public:
		INetSession(boost::asio::io_service& io_service);
		virtual ~INetSession();/* = 0;*/

		void Start();
		void Close();
		void Send(PacketHeader* packet);
		IoBuffer* GetFrontIoBuffer();
		void PushIoBuffer(IoBuffer* buffer);
		
		boost::asio::ip::tcp::socket& GetSocket();
		std::string GetRemoteIp();

	private:
		void SendImp();
		void WriteHandle(boost::system::error_code ec, std::size_t transfer_length, IoBuffer* data);
		void ReadHandle(boost::system::error_code ec, std::size_t transfer_length, char* rb0, char* rb1);

	public:
		boost::function<void()> connect_callback_;
		boost::function<void()> connect_failed_callback_;
		boost::function<void()> connect_lost_callback_;
		boost::function<void(char* buf, void* obj)> receive_callback_;

	private:
		char state_;
		boost::asio::ip::tcp::socket socket_;

		std::queue<IoBuffer*> send_buffer_queue_;
		int cur_send_count_;

		char read_buffers_[2][PacketHeader::PACKET_MAX_SIZE];
		int read_buffer_remain_length_;

	};

	typedef boost::shared_ptr<INetSession> INetSessionPtr;
}

#endif;